package com.middleware.redis;


import org.springframework.data.redis.core.script.RedisScript;
import org.springframework.stereotype.Component;

/**
 * 脚本模板
 *
 * @author Mr.Zhong
 * @description
 * @date 2022/04/20 14:41
 */
@Component
public class RedisScriptTemplate {


    /**
     * 访问限制
     */
    public static final RedisScript<Boolean> MOBILE_ARMOR_EXPIRE_SCRIPT;

    /**
     * 秒杀扣减库存
     */
    public static final RedisScript<Long> ACTIVITY_NUMBER_SECKILL;

    static {
        StringBuilder sb = new StringBuilder();
        //  获取第一个键值为手机号mobile
        sb.append("local mobile = KEYS[1]; \n");
        //  获取第一个参数值间隔时间为con
        sb.append("\tlocal con = tonumber(ARGV[1]); \n");
        //  根据手机号为key查询并返回值result
        sb.append("\tlocal result = redis.call('exists','MOBILE_ARMOR'..mobile );\n");
        //  查询结果为1为返回false
        sb.append("\tif(result == 1)  then\n");
        sb.append("\treturn false;\n");
        sb.append("\tend\n");
        //  写入一个key为手机号,并设置过期时间为con秒的值,并返回true
        sb.append("\tredis.call('setex','MOBILE_ARMOR'..mobile,con,1);\n");
        sb.append("\treturn true;\n");
        MOBILE_ARMOR_EXPIRE_SCRIPT = new RedisScriptImpl<>(sb.toString(), Boolean.class);
    }


    static {
        StringBuilder sb = new StringBuilder();
        //  获取第一个键值为活动id
        sb.append("local activityId = KEYS[1]; \n");
        //  获取第一个参数值扣减库存数为con
        sb.append("\tlocal con = tonumber(ARGV[1]); \n");
        //  获取以活动id为key的值当前总库存数
        sb.append("\tlocal remain = tonumber(redis.call('get','ACTIVITY_NUMBER'..activityId) or 0);\n");
        //  如果当前库存数小于需要扣减的库存数返回0
        sb.append("\tif remain < con then\n");
        sb.append("\treturn 0;\n");
        sb.append("\tend\n");
        //  从总库存中减去扣减库存数并返回当前库存数result值
        sb.append("\tlocal result = redis.call('decrby','ACTIVITY_NUMBER'..activityId,con );\n");
        //  如果当前库存大于0返回1否则返回-1
        sb.append("\tif result > 0 then\n");
        sb.append("\treturn 1;\n");
        sb.append("\tend\n");
        sb.append("\treturn -1;\n");
        ACTIVITY_NUMBER_SECKILL = new RedisScriptImpl<>(sb.toString(), Long.class);
    }


}
